broadway: Handle browser hidpi scale factor
authorAlexander Larsson <alexl@redhat.com>
Thu, 12 Mar 2020 10:12:01 +0000 (11:12 +0100)
committerAlexander Larsson <alexl@redhat.com>
Fri, 13 Mar 2020 13:59:37 +0000 (14:59 +0100)
gdk/broadway/broadway-protocol.h
gdk/broadway/broadway-server.c
gdk/broadway/broadway-server.h
gdk/broadway/broadway.js
gdk/broadway/broadwayd.c
gdk/broadway/gdkdisplay-broadway.c
gdk/broadway/gdkdisplay-broadway.h
gdk/broadway/gdksurface-broadway.c
gsk/broadway/gskbroadwayrenderer.c

index 3f73f137711a96253ef0f447c16b4d8580d933b2..436d60da49cecb98758370aed68d6f1e2040be33 100644 (file)
@@ -165,6 +165,7 @@ typedef struct {
   BroadwayInputBaseMsg base;
   guint32 width;
   guint32 height;
+  guint32 scale;
 } BroadwayInputScreenResizeNotify;
 
 typedef struct {
index 24fd7bf51c63abe69dd6f07e7e96b2c91608685c..f7a380ec268033b2d640ed7b8ece876f812555f2 100644 (file)
@@ -67,8 +67,7 @@ struct _BroadwayServer {
   guint32 next_texture_id;
   GHashTable *textures;
 
-  guint32 screen_width;
-  guint32 screen_height;
+  guint32 screen_scale;
 
   gint32 mouse_in_surface_id;
   int last_x, last_y; /* in root coords */
@@ -273,6 +272,7 @@ broadway_server_init (BroadwayServer *server)
   root->visible = TRUE;
 
   server->root = root;
+  server->screen_scale = 1;
 
   g_hash_table_insert (server->surface_id_hash,
                        GINT_TO_POINTER (root->id),
@@ -428,6 +428,7 @@ update_event_state (BroadwayServer *server,
   case BROADWAY_EVENT_SCREEN_SIZE_CHANGED:
     server->root->width = message->screen_resize_notify.width;
     server->root->height = message->screen_resize_notify.height;
+    server->screen_scale = message->screen_resize_notify.scale;
     break;
 
   default:
@@ -722,6 +723,7 @@ parse_input_message (BroadwayInput *input, const unsigned char *message)
   case BROADWAY_EVENT_SCREEN_SIZE_CHANGED:
     msg.screen_resize_notify.width = ntohl (*p++);
     msg.screen_resize_notify.height = ntohl (*p++);
+    msg.screen_resize_notify.scale = ntohl (*p++);
     break;
 
   default:
@@ -958,10 +960,12 @@ broadway_server_get_next_serial (BroadwayServer *server)
 void
 broadway_server_get_screen_size (BroadwayServer   *server,
                                  guint32          *width,
-                                 guint32          *height)
+                                 guint32          *height,
+                                 guint32          *scale)
 {
   *width = server->root->width;
   *height = server->root->height;
+  *scale = server->screen_scale;
 }
 
 static void
index f11e9e872df84021571bc663b0ec9ba5885d7d41..10181c3d795b0ad2ea47f5e1894215b786453245 100644 (file)
@@ -64,7 +64,8 @@ void                broadway_server_roundtrip                 (BroadwayServer  *
                                                                guint32          tag);
 void                broadway_server_get_screen_size           (BroadwayServer  *server,
                                                                guint32         *width,
-                                                               guint32         *height);
+                                                               guint32         *height,
+                                                               guint32         *scale);
 guint32             broadway_server_get_next_serial           (BroadwayServer  *server);
 guint32             broadway_server_get_last_seen_time        (BroadwayServer  *server);
 gboolean            broadway_server_lookahead_event           (BroadwayServer  *server,
index ba2fdcd7279d5762d0e92c224a1eca3b668b7b57..793aa56bea26bc5e45aa124c96e5d4221531958c 100644 (file)
@@ -3184,20 +3184,32 @@ function setupDocument(document)
     }
 }
 
+function sendScreenSizeChanged() {
+    var w, h, s;
+    w = window.innerWidth;
+    h = window.innerHeight;
+    s = Math.round(window.devicePixelRatio);
+    sendInput (BROADWAY_EVENT_SCREEN_SIZE_CHANGED, [w, h, s]);
+}
+
 function start()
 {
     setupDocument(document);
 
-    var w, h;
-    w = window.innerWidth;
-    h = window.innerHeight;
     window.onresize = function(ev) {
-        var w, h;
-        w = window.innerWidth;
-        h = window.innerHeight;
-        sendInput (BROADWAY_EVENT_SCREEN_SIZE_CHANGED, [w, h]);
+        sendScreenSizeChanged();
     };
-    sendInput (BROADWAY_EVENT_SCREEN_SIZE_CHANGED, [w, h]);
+    window.matchMedia('screen and (min-resolution: 2dppx)').
+        addListener(function(e) {
+                        if (e.matches) {
+                            /* devicePixelRatio >= 2 */
+                            sendScreenSizeChanged();
+                        } else {
+                            /* devicePixelRatio < 2 */
+                            sendScreenSizeChanged();
+                        }
+                    });
+    sendScreenSizeChanged();
 }
 
 function connect()
index 54d97c5ec108d1d4248a29f7a735cb92624229c1..d65e69c4ceef978dbda47e448d6a8dde143b56f8 100644 (file)
@@ -513,7 +513,8 @@ incoming_client (GSocketService    *service,
   ev.base.time = broadway_server_get_last_seen_time (server);
   broadway_server_get_screen_size (server,
                                    &ev.screen_resize_notify.width,
-                                   &ev.screen_resize_notify.height);
+                                   &ev.screen_resize_notify.height,
+                                   &ev.screen_resize_notify.scale);
 
   broadway_events_got_input (&ev,
                              client->id);
index 3beefc46361004cc464c6b3dbae9d152208d358f..db7428719f2dbd39af99252be7d2a4dbb8db580b 100644 (file)
@@ -63,6 +63,10 @@ gdk_broadway_display_init (GdkBroadwayDisplay *display)
                                    NULL);
   gdk_monitor_set_manufacturer (display->monitor, "browser");
   gdk_monitor_set_model (display->monitor, "0");
+  display->scale_factor = 1;
+  gdk_monitor_set_size (display->monitor, 1024, 768);
+  gdk_monitor_set_physical_size (display->monitor, 1024 * 25.4 / 96, 768 * 25.4 / 96);
+  gdk_monitor_set_scale_factor (display->monitor, 1);
 }
 
 static void
@@ -80,16 +84,21 @@ _gdk_broadway_display_size_changed (GdkDisplay                      *display,
 {
   GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (display);
   GdkMonitor *monitor;
-  GdkRectangle size;
+  GdkRectangle current_size;
   GList *toplevels, *l;
 
   monitor = broadway_display->monitor;
-  gdk_monitor_get_geometry (monitor, &size);
+  gdk_monitor_get_geometry (monitor, &current_size);
 
-  if (msg->width == size.width && msg->height == size.height)
+  if (msg->width == current_size.width &&
+      msg->height == current_size.height &&
+      msg->scale == broadway_display->scale_factor)
     return;
 
+  broadway_display->scale_factor = msg->scale;
+
   gdk_monitor_set_size (monitor, msg->width, msg->height);
+  gdk_monitor_set_scale_factor (monitor, msg->scale);
   gdk_monitor_set_physical_size (monitor, msg->width * 25.4 / 96, msg->height * 25.4 / 96);
 
   toplevels =  broadway_display->toplevels;
@@ -101,8 +110,7 @@ _gdk_broadway_display_size_changed (GdkDisplay                      *display,
         gdk_broadway_surface_move_resize (GDK_SURFACE (toplevel),
                                           0, 0,
                                           msg->width, msg->height);
-    }
-}
+    }}
 
 static GdkDevice *
 create_core_pointer (GdkDisplay       *display)
index a8d6819c8292ddc7b0dcee3856d75007f85d51ad..b8e11168ef1980be3c8a053009f7eb172d2539b1 100644 (file)
@@ -50,10 +50,10 @@ struct _GdkBroadwayDisplay
   GdkKeymap *keymap;
 
   GdkBroadwayServer *server;
-
   gpointer move_resize_data;
 
   GdkMonitor *monitor;
+  int scale_factor;
 
   GHashTable *texture_cache;
 
index ed377a3ca3b1c60215d3c90df7e8c251059a4750..0193f499b2e0acf2a3ad32f080301235da865e2a 100644 (file)
@@ -386,6 +386,19 @@ gdk_broadway_surface_hide (GdkSurface *surface)
   _gdk_surface_clear_update_area (surface);
 }
 
+static gint
+gdk_broadway_surface_get_scale_factor (GdkSurface *surface)
+{
+  GdkBroadwayDisplay *broadway_display;
+
+  if (GDK_SURFACE_DESTROYED (surface))
+    return 1;
+
+  broadway_display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface));
+
+  return broadway_display->scale_factor;
+}
+
 static void
 gdk_broadway_surface_move_resize_internal (GdkSurface *surface,
                                            gboolean    with_move,
@@ -1249,6 +1262,7 @@ gdk_broadway_surface_class_init (GdkBroadwaySurfaceClass *klass)
   impl_class->begin_move_drag = gdk_broadway_surface_begin_move_drag;
   impl_class->destroy_notify = gdk_broadway_surface_destroy_notify;
   impl_class->drag_begin = _gdk_broadway_surface_drag_begin;
+  impl_class->get_scale_factor = gdk_broadway_surface_get_scale_factor;
 }
 
 #define LAST_PROP 1
index 1dbfc9c11c751c12969f2424441a34c98efed5ea..cb46f92bc2eed888a4ea0035245d08437b71d430 100644 (file)
@@ -477,6 +477,7 @@ gsk_broadway_renderer_add_node (GskRenderer *renderer,
                                 float offset_y)
 {
   GdkDisplay *display = gdk_surface_get_display (gsk_renderer_get_surface (renderer));
+  GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (display);
   GskBroadwayRenderer *self = GSK_BROADWAY_RENDERER (renderer);
   GArray *nodes = self->nodes;
 
@@ -753,9 +754,11 @@ gsk_broadway_renderer_add_node (GskRenderer *renderer,
       int y = floorf (node->bounds.origin.y);
       int width = ceil (node->bounds.origin.x + node->bounds.size.width) - x;
       int height = ceil (node->bounds.origin.y + node->bounds.size.height) - y;
+      int scale = broadway_display->scale_factor;
 
-      surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+      surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width * scale, height * scale);
       cr = cairo_create (surface);
+      cairo_scale (cr, scale, scale);
       cairo_translate (cr, -x, -y);
       gsk_render_node_draw (node, cr);
       cairo_destroy (cr);
@@ -766,8 +769,8 @@ gsk_broadway_renderer_add_node (GskRenderer *renderer,
       texture_id = gdk_broadway_display_ensure_texture (display, texture);
       add_float (nodes, x - offset_x);
       add_float (nodes, y - offset_y);
-      add_float (nodes, gdk_texture_get_width (texture));
-      add_float (nodes, gdk_texture_get_height (texture));
+      add_float (nodes, width);
+      add_float (nodes, height);
       add_uint32 (nodes, texture_id);
     }
 }